package com.gitee.wsl.prism4j.languages

import com.gitee.wsl.prism4j.Prism4j
import com.gitee.wsl.prism4j.Prism4j.Companion.grammar
import com.gitee.wsl.prism4j.Prism4j.Companion.pattern
import com.gitee.wsl.prism4j.Prism4j.Companion.token
import com.gitee.wsl.prism4j.Prism4j.Pattern

@Suppress("unused")
object Prism_makefile {
    fun create(prism4j: Prism4j): Prism4j.Grammar {
        return grammar(
            "makefile",
            token(
                "comment", pattern(
                    Pattern.compile("(^|[^\\\\])#(?:\\\\(?:\\r\\n|[\\s\\S])|[^\\\\\\r\\n])*"),
                    true
                )
            ),
            token(
                "string", pattern(
                    Pattern.compile("([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1"),
                    false,
                    true
                )
            ),
            token("builtin", pattern(Pattern.compile("\\.[A-Z][^:#=\\s]+(?=\\s*:(?!=))"))),
            token(
                "symbol", pattern(
                    Pattern.compile("^[^:=\\r\\n]+(?=\\s*:(?!=))", Pattern.MULTILINE),
                    false,
                    false,
                    null,
                    grammar(
                        "inside",
                        token("variable", pattern(Pattern.compile("\\$+(?:[^(){}:#=\\s]+|(?=[({]))")))
                    )
                )
            ),
            token("variable", pattern(Pattern.compile("\\$+(?:[^(){}:#=\\s]+|\\([@*%<^+?][DF]\\)|(?=[({]))"))),
            token(
                "keyword",
                pattern(Pattern.compile("-include\\b|\\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\\b")),
                pattern(
                    Pattern.compile("(\\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \\t])"),
                    true
                )
            ),
            token("operator", pattern(Pattern.compile("(?:::|[?:+!])?=|[|@]"))),
            token("punctuation", pattern(Pattern.compile("[:;(){}]")))
        )
    }
}
